home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
RTF
/
textflow.h
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
165 lines
/* $Header: /usr/people/pcd/Src/RTF/RCS/textflow.h,v 1.1 92/11/23 12:58:52 pcd Exp Locker: pcd $
*/
#ifndef __textflow_h
#define __textflow_h
#include "space.h"
typedef unsigned char Byte;
typedef long Qty;
/*
* A flow of text is a contiguous array of bytes.
* No restrictions are placed on the contents of the bytes,
* or the number of bytes that determine a character glyph.
* i.e. a flow of text is a superset of the C string
* conventions.
*/
class Node{
/*
* These are Nodes in a nary tree.
* The tree is always at least two levels deep,
* and n->parent() == n iff n is the root.
*/
public:
const Node* parent() const { return parent_; };
Node* left() const { return left_; };
Node* right() const { return right_; };
protected:
Node(Node* parent);
/* USE : assert(parent != 0);
* Node(parent);
******/
Node(Node* parent, Node* left_sibling, Node* right_child);
/* USE : if(left_sibling){
* assert(parent == left_sibling->parent());
* for(Node* x = left->sibling->right(); x; x=x->right())
* if(x == right_child)
* break;
* assert(x == right_child);
* }
* if(right_sibling)
* assert(right_sibling->parent() == parent);
* n = new Node(parent, left_sibling, right_child);
* assert(n->parent() == parent);
* assert(n->left() == left_sibling);
* assert(n->right_child() == right_child);
* assert(left_sibling || parent->left_child() == n);
******/
~Node();
void connect(Node*, Node*);
void consume(Node*);
void disconnect();
Node* left_child() const { return left_child_; };
Node* right_child() const { return right_child_; };
private:
Node* parent_; // can't be 0
Node* left_;
Node* right_;
Node* left_child_; // zero only for leaves
Node* right_child_;
};
class TextFlow: public Node{
/******
*
* A TextFlow treats a TextFlow as a flow of structured text.
* and n->left_child() == 0 iff n->right_child() == 0 iff n is a leaf,
*
******/
public:
/*******/
TextFlow(const Byte* data, Qty siz);
/* USE : assert(qty > 0;
* assert(data[siz-1] = 1); // i.e. can write to data[siz-1] NOTATION
* textflow = new TextFlow(data, siz);
*******/
~TextFlow();
Qty bytes() const { return bytes_; };
const Byte* data() const
{ return data_; };
Qty bytes_before() const;
Qty bytes_after() const;
/****************/
const TextFlow* subflow(TextPosition first, TextPosition last) const;
/* DESC: get a substructure from the flow
* USE : assert(first <= last);
* tf = textflow->subflow(first, last);
****************/
const TextFlow* leaf(TextPosition, TextPosition& move) const;
/*@#
*******************/
/*******/
Qty read(Byte* dest, TextPosition first, TextPosition last) const;
/* DESC: retrieve bytes from a textflow
* USE : textflow = new TextFlow(data, qty)
* assert(first <= last);
* assert(first == last || dest[last-first-1] = 1);
* qty = textflow->read(dest, first, last);
* assert(qty <= last - first);
* assert(IMPLIES(first < qty,
* memcmp(data+first, dest, min(qty-first, last-first)) ));
*******/
/**************/
virtual void line_shape(TextPosition, Extent& shape) const;
/*@#
**************/
/**************/
virtual Qty character_shape(TextPosition first, Qty q,
Extent, Extent& used, int) const;
/* USE : assert(first <= last);
* qty = textflow->character_shape(first, q, avail, used, w);
* assert(qty <= last - first);
* assert(qty == 0 || used < avail); //@# Extent::operator<
**************/
/**********/
virtual void render(TextPosition, Qty, Point) const;
/* DESC: default behavior inherits from parent.
* subclasses should draw the text.
***********/
TextFlow* parent() const
{ return (TextFlow*)Node::parent(); };
virtual void parse()
{ };
protected:
TextFlow(TextFlow& parent, TextFlow* left, const Byte*, Qty);
TextFlow(TextFlow&, Qty, Qty);
/* relatives of TextFlows are known to be TextFlows */
TextFlow* left() const { return (TextFlow*)Node::left(); };
TextFlow* right() const { return (TextFlow*)Node::right(); };
TextFlow* left_child() const { return (TextFlow*)Node::left_child(); };
TextFlow* right_child() const { return (TextFlow*)Node::right_child(); };
private:
TextFlow* start_branch(Qty);
TextFlow* end_branch(Qty);
Byte* data_;
Qty bytes_;
};
#endif